package org.rcy.framework.thrift.serializer;

import net.qiyuesuo.rpc.thrift.TEnum;
import net.qiyuesuo.rpc.thrift.metadata.EnumMetaData;
import net.qiyuesuo.rpc.thrift.metadata.FieldValueMetaData;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TProtocol;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * enum类型数据以string格式保存
 * 
 * @author zhouree
 */
public class EnumSerializer implements Serializer {

	@Override
	public Object read(TProtocol iprot, FieldValueMetaData valueMetaData) throws TException {
		EnumMetaData enumMetaData = (EnumMetaData) valueMetaData;
		Class<?> enumClass = enumMetaData.enumClass;
		// 实现了TEnum接口的Enum对象按I32格式读取
		if (TEnum.class.isAssignableFrom(enumClass)) {
			int value = iprot.readI32();
			try {
				List<Enum> constants = Arrays.asList((Enum[]) enumClass.getEnumConstants());
				Optional<Enum> optional = constants.stream().filter(e -> ((TEnum) e).getValue() == value).findFirst();
				return optional.isPresent() ? optional.get() : null;
			} catch (Exception e) {
				throw new TException(e);
			}
		}
		// 默认按String读取
		if (Enum.class.isAssignableFrom(enumClass)) {
			String name = iprot.readString();
			try {
				List<Enum> constants = Arrays.asList((Enum[]) enumClass.getEnumConstants());
				Optional<Enum> optional = constants.stream().filter(e -> e.name().equals(name)).findFirst();
				return optional.isPresent() ? optional.get() : null;
			} catch (Exception e) {
				throw new TException(e);
			}
		}
		return null;
	}

	@Override
	public void write(TProtocol oprot, FieldValueMetaData valueMetaData, Object value) throws TException {
		if (value == null) {
			return;
		}
		// 实现了TEnum接口的Enum类用I32格式保存
		if (value instanceof TEnum) {
			TEnum e = (TEnum) value;
			oprot.writeI32(e.getValue());
			return;
		}
		// 默认按照String保存
		if (value instanceof Enum) {
			Enum e = (Enum) value;
			oprot.writeString(e.name());
			return;
		}
	}
}
